// SmartTable.tsx
import {
  defineComponent,
  PropType,
  ref,
  watchEffect,
  computed,
  onMounted,
  onBeforeUnmount,
} from "vue";
import { Table, Empty, message, Row, Space } from "ant-design-vue";
import type {
  TableProps,
  ColumnType,
  TablePaginationConfig,
} from "ant-design-vue/es/table";
import { debounce } from "lodash-es";
import "./table.less";
import { type AxiosHeaders } from "axios";
import mitter from "@/utils/bus";
import { storage } from '@/storage'

type RequestParams = {
  page: number;
  pageSize: number;
  sorter?: any;
  filters?: Record<string, any>;
};

interface AxiosResponseInfo<T = any> {
  config: any;
  headers: AxiosHeaders;
  request: XMLHttpRequest;
  status: number;
  statusText: string;
  data: T;
}

type RequestFunction = (params: RequestParams) => Promise<
  AxiosResponseInfo<{
    code: string;
    msg: string;
    respTime: string;
    data: any[];
    total: number;
  }>
>;

type DeleteFunction = (ids: (string | number)[]) => any;

export default defineComponent({
  name: "VTable",
  props: {
    // 请求函数
    request: {
      type: Function as PropType<RequestFunction>,
      required: true,
    },
    deleteRequest: Function as PropType<DeleteFunction>,
    // 列配置
    columns: {
      type: Array as PropType<ColumnType[]>,
      required: true,
    },
    // 自动发起请求
    autoRequest: {
      type: Boolean,
      default: true,
    },
    params: {
      type: Object as any,
      default: () => ({}),
    },
    isReload: {
      type: Boolean,
      default: false,
    },
    // 初始分页参数
    initParams: {
      type: Object as PropType<Omit<RequestParams, "list" | "total">>,
      default: () => ({
        page: 1,
        pageSize: 10,
      }),
    },
    // 分页配置
    paginationConfig: {
      type: Object as PropType<Partial<TablePaginationConfig>>,
      default: () => ({}),
    },
    // 新增勾选配置
    rowSelection: {
      type: [Object, Boolean] as PropType<boolean | TableProps["rowSelection"]>,
      default: false,
    },
    // 新增序号列配置
    showIndexColumn: {
      type: [Boolean, Object] as PropType<boolean | ColumnType>,
      default: false,
    },
    preserveSelectedRowKeys: {
      type: Boolean,
      default: true,
    },
    rowKey: {
      type: [String, Function] as PropType<string | ((record: any) => string)>,
      default: "id",
    },
    mainHeight: {
      type: [Number, String],
      default: 800,
    },
    offsetNumber: {
      type: Number,
      default: 260,
    }
  },
  emits: [
    "request-success",
    "request-error",
    "selection-change",
    "delete-success",
    'update:isReload'
  ],
  setup(props, { emit, expose, slots }) {
    // 状态管理
    const loading = ref(false);
    const dataSource = ref<any[]>([]);
    const pagination = ref({
      current: props.initParams.page,
      pageSize: props.initParams.pageSize,
      total: 0,
    });
    const sorter = ref<any>();
    const filters = ref<Record<string, any>>();
    const selectedRowKeys = ref<(string | number)[]>([]);
    const selectedRows = ref<any[]>([]);

    // 合并分页配置
    const mergedPagination = computed(() => ({
      ...pagination.value,
      ...props.paginationConfig,
      showTotal: (total: number) => `共 ${total} 条`,
      showSizeChanger: true,
      pageSizeOptions: ["10", "20", "50", "100"],
    }));

    // 处理勾选配置
    const mergedRowSelection = computed(() => {
      if (!props.rowSelection) return undefined;
      const defaultConfig: TableProps["rowSelection"] = {
        type: "checkbox",
        selectedRowKeys: selectedRowKeys.value,
        onChange: (keys, rows) => {
          selectedRowKeys.value = keys;
          selectedRows.value = rows;
          emit("selection-change", { keys, rows });
        },
        preserveSelectedRowKeys: props.preserveSelectedRowKeys,
      };

      return typeof props.rowSelection === "boolean"
        ? defaultConfig
        : { ...defaultConfig, ...props.rowSelection };
    });

    // 处理带插槽的列配置
    const processedColumns = computed(() => {
      const cols: any[] = [...props.columns];
      // 添加序号列
      if (props.showIndexColumn) {
        const indexColumn: ColumnType = {
          title: "序号",
          key: "index",
          width: 80,
          align: "center",
          customRender: ({ index }) => {
            if (slots.indexColumn) {
              return slots.indexColumn({ index });
            }
            const current = pagination.value.current || 1;
            const pageSize = pagination.value.pageSize || 10;
            return (current - 1) * pageSize + index + 1;
          },
          ...(typeof props.showIndexColumn === "object"
            ? props.showIndexColumn
            : {}),
        };
        cols.unshift(indexColumn);
      }

      // 处理插槽列
      return cols.map((col) => {
        if (!col.slotName) return col;
        return {
          ...col,
          customRender: ({ text, record, index }) => {
            const slotName = col.slotName;
            return slots[slotName]?.({ text, record, index }) || text;
          },
        };
      });
    });

    // 处理表头插槽
    const processedHeaderSlots = computed(() => {
      const headerSlots: Record<string, any> = {};
      props.columns.forEach((col: any) => {
        if (col.slotName) {
          const slotName = `header:${col.slotName}`;
          if (slots[slotName]) {
            headerSlots[`header:${col.dataIndex}`] = () =>
              slots[slotName]!({ column: col });
          }
        }
      });
      return headerSlots;
    });

    const autoAdjustPagination = () => {
      // 满足三个条件时调整分页：
      // 1. 当前数据为空
      // 2. 当前不是第一页
      // 3. 总数据量大于0
      if (
        dataSource.value.length === 0 &&
        pagination.value.current > 1 &&
        pagination.value.total > 0
      ) {
        const totalPage = Math.ceil(
          pagination.value.total / pagination.value.pageSize
        );
        const newCurrent = Math.min(pagination.value.current - 1, totalPage);

        if (newCurrent !== pagination.value.current) {
          pagination.value.current = newCurrent;
          return true; // 需要重新请求
        }
      }
      return false;
    };

    const handleDelete = async (ids: (string | number)[]) => {
      if (!props.deleteRequest) {
        message.warning("未配置删除方法");
        return;
      }
      try {
        await props.deleteRequest!(ids);
        message.success("删除成功");
        const deleteCount = ids.length;

        // 更新分页信息
        pagination.value.total -= deleteCount;

        // 检查是否需要调整分页
        if (
          dataSource.value.length === deleteCount &&
          pagination.value.current > 1
        ) {
          const totalPage = Math.ceil(
            pagination.value.total / pagination.value.pageSize
          );
          pagination.value.current = Math.min(
            pagination.value.current,
            totalPage
          );
        }
        // 重新加载数据
        await fetchData();
        emit("delete-success", ids);
      } catch (error) {}
    };

    // 执行请求
    const fetchData = async () => {
      try {
        loading.value = true;
        const values = {
          ...props.params,
          page: pagination.value.current,
          pageSize: pagination.value.pageSize,
          // sorter: sorter.value,
          // filters: filters.value,
        };

        const resp = await props.request(values);
        const { data, total } = resp.data;

        const shouldReload = autoAdjustPagination();
        if (shouldReload) {
          await fetchData(); // 递归调用
          return;
        }
        dataSource.value = data;
        pagination.value.total = total;
        emit("request-success", { data: data, values });
      } catch (error) {
        emit("request-error", error);
      } finally {
        loading.value = false;
        emit('update:isReload', false)
      }
    };

    const heightAct = storage.local.get("actionHeight") as string
    const tableHeight = ref();
    const actionHeight = ref(parseInt(heightAct) || 100);
    // 计算可用高度（示例：视口高度 - 其他元素高度）
    const calculateHeight = debounce(() => {
      const pageControl = 30; // 分页器高度（如果有）
      // 视口高度 - 其他元素总高度
      const height =
        (props.mainHeight as number) -
        props.offsetNumber -
        pageControl -
        actionHeight.value;
      tableHeight.value = Math.max(height, 200); // 最小高度 200px
    }, 150);

    onMounted(() => {
      calculateHeight()
      window.addEventListener("resize", calculateHeight);
      mitter.on("resetHeight", (val) => {
        actionHeight.value = val;
        calculateHeight();
      });
    });

    // 销毁时移除监听
    onBeforeUnmount(() => {
      window.removeEventListener("resize", calculateHeight);
      mitter.off("resetHeight");
    });

    const debouncedFetch = debounce(fetchData, 300);

    // 修改监听器
    watchEffect(() => {
      if (props.autoRequest) {
        debouncedFetch();
      }
    });

    watch(
      () => props.params,
      () => {
        debouncedFetch();
      },
      {
        deep: true,
      }
    );

    watch(
      () => props.isReload,
      (val) => {
        if (props.autoRequest) {
          if (val) {
            debouncedFetch();
          }
        }
      }
    );

    // 表格变化处理器
    const handleTableChange = (
      newPagination: TablePaginationConfig,
      newFilters: Record<string, any>,
      newSorter: any
    ) => {
      pagination.value = {
        ...pagination.value,
        current: newPagination.current || 1,
        pageSize: newPagination.pageSize || 10,
      };
      // filters.value = newFilters;
      // sorter.value = newSorter as any;
      debouncedFetch();
    };

    const reload = () => {
      selectedRowKeys.value = [];
      selectedRows.value = [];
      debouncedFetch();
    };

    // 暴露方法
    expose({
      reload,
      handleDelete,
      getParams: () => ({
        page: pagination.value.current,
        pageSize: pagination.value.pageSize,
        sorter: sorter.value,
        filters: filters.value,
      }),
      getSelection: () => ({
        keys: selectedRowKeys.value,
        rows: selectedRows.value,
      }),
      clearSelection: () => {
        selectedRowKeys.value = [];
        selectedRows.value = [];
      },
    });

    return () => (
      <div class="smart-table-wrapper">
        <Row style={{ marginBottom: "20px" }}>
          <Space>
            <>{slots.headerActions?.()}</>
          </Space>
        </Row>
        <Table
          class={"animated-table"}
          columns={processedColumns.value}
          dataSource={dataSource.value}
          pagination={mergedPagination.value}
          rowSelection={mergedRowSelection.value}
          loading={loading.value}
          scroll={{ y: tableHeight.value }}
          bordered
          row-key={props.rowKey}
          onChange={handleTableChange}
          v-slots={{
            ...processedHeaderSlots.value,
            emptyText: () =>
              slots.empty?.() || (
                <Empty
                  image={Empty.PRESENTED_IMAGE_SIMPLE}
                  description="暂无数据"
                />
              ),
            expandedRowRender: slots.expandedRow
              ? ({ record, index }) => slots.expandedRow!({ record, index })
              : undefined,
          }}
        ></Table>
      </div>
    );
  },
});
